package com.bourne.util;

import com.bourne.constant.NumConstant;
import com.bourne.constant.StringConstant;
import com.bourne.enums.StringEnum;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @program prkManagement
 * @description
 * @author: bourne
 * @create 2021-41-06 19:41:41
 **/
public class RSAUtils {

    /**
     * 生成随机秘钥对
     * @throws NoSuchAlgorithmException
     */
    public static Map<String,String> genKeyPair() throws NoSuchAlgorithmException {

        Map<String,String> keyMap = new HashMap<>();
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(StringConstant.RSA_ENCRYPTION);
        keyPairGen.initialize(NumConstant.NUM_BIRTHDAY, new SecureRandom());
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        keyMap.put(StringEnum.PUB_KEY.name(), publicKeyString);
        keyMap.put(StringEnum.PRI_KEY.name(), privateKeyString);

        return keyMap;
    }

    /**
     * RSA公钥加密
     * @param str
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String str, String publicKey ) throws Exception{
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(StringConstant.RSA_ENCRYPTION)
                .generatePublic(new X509EncodedKeySpec(decoded));
        //RSA加密
        Cipher cipher = Cipher.getInstance(StringConstant.RSA_ENCRYPTION);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * RSA私钥解密
     * @param str
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String str, String privateKey) throws Exception{
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(StringConstant.RSA_ENCRYPTION)
                .generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance(StringConstant.RSA_ENCRYPTION);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte));
    }
}
